import { defineComponent, computed, reactive, watch, watchEffect, createVNode, createTextVNode } from 'vue';
import VirtualList from '../virtual-list/index.js';
import formFieldRef from '../use/formFieldRef.js';
import Checkbox from '../inner/Checkbox.js';
import Text from '../Typography/Text.js';
import { FeatherSearch, FeatherX } from 'cui-vue-icons/feather';
import Button from '../Button/index.js';
import Input from '../FormElements/Input/index.js';

const index = /* @__PURE__ */ defineComponent({
  name: 'TeleportBox',
  props: {
    data: {
      type: Array,
      default: () => []
    },
    modelValue: {
      type: Array,
      default: () => []
    },
    defaultValue: {
      type: Array
    },
    disabled: {
      type: Boolean
    },
    virtual: {
      type: Boolean
    },
    renderSourceItem: {
      type: Function
    },
    renderSelectedItem: {
      type: Function
    },
    filter: {
      type: Function
    }
  },
  emits: ['update:modelValue', 'change'],
  setup(props, {
    emit,
    slots
  }) {
    const classList = computed(() => ({
      'cm-teleport-box': true,
      'cm-teleport-box--disabled': props.disabled
    }));
    const value = formFieldRef(props, emit, []);
    const store = reactive({
      leftList: [],
      rightList: [],
      originList: [],
      flatList: [],
      dataMap: {},
      checkedAll: false
    });
    const onFilter = v => {
      if (v) {
        const list = store.flatList?.filter(item => {
          if (props.filter) {
            return props.filter(item, v);
          }
          if (item.children?.length) {
            const childs = item.children?.filter(sub => item.label.includes(v));
            return childs?.length;
          }
          return item.label.includes(v);
        });
        store.leftList = list || [];
      } else {
        store.leftList = store.flatList || [];
      }
    };
    const initData = () => {
      const map = {};
      let originList = [];
      const vals = value.value;
      if (props.defaultValue) {
        props.defaultValue.forEach(v => {
          if (!vals.includes(v)) {
            vals.push(v);
          }
        });
      }
      const list = props.data?.flatMap(item => {
        if (item.children?.length) {
          originList = originList.concat(item.children);
        } else {
          originList.push(item);
        }
        return [item, ...(item.children ? item.children : [])].flat();
      });
      list?.forEach(item => {
        if (vals.includes(item.value)) {
          item.checked = true;
        }
        map[item.value] = item;
      });
      store.originList = originList;
      store.flatList = list || [];
      store.dataMap = map;
      store.leftList = list || [];
      value.value = [...vals];
    };
    initData();
    watch(() => props.data, () => {
      initData();
    });
    watchEffect(() => {
      const val = value.value;
      const total = store.originList.filter(item => !item.disabled || item.disabled && item.checked).length;
      if (props.data?.length && val.length === total) {
        store.checkedAll = true;
      } else {
        store.checkedAll = false;
      }
      const arr = val.map(v => {
        return store.dataMap[v];
      });
      store.rightList = arr;
    });
    const onChecked = (checked, item) => {
      if (props.disabled || item.disabled) {
        return;
      }
      item.checked = checked;
      let val = value.value || [];
      const v = item.value;
      if (checked) {
        if (!val.includes(v)) {
          val = val.concat(v);
        }
      } else {
        const index = val.indexOf(v);
        if (index > -1) {
          val.splice(index, 1);
        }
      }
      value.value = [...val];
      emit('change', value.value);
    };
    const onRemoveItem = item => {
      if (item.disabled) {
        return;
      }
      item.checked = false;
      const val = value.value;
      const index = val.indexOf(item.value);
      if (index > -1) {
        val.splice(index, 1);
      }
      value.value = [...val];
      emit('change', value.value);
    };
    const clearAll = () => {
      const vals = value.value;
      const restVals = [];
      vals.forEach(val => {
        const item = store.dataMap[val];
        if (item.disabled) {
          restVals.push(item.value);
          return;
        }
        item.checked = false;
      });
      value.value = restVals;
      emit('change', restVals);
    };
    const selectAll = () => {
      const vals = [];
      for (const val in store.dataMap) {
        const item = store.dataMap[val];
        if (item.children?.length) {
          continue;
        }
        if (item.disabled) {
          if (item.checked) {
            vals.push(item.value);
          }
          continue;
        }
        item.checked = true;
        vals.push(item.value);
      }
      value.value = vals;
      emit('change', vals);
    };
    const renderSourceList = () => {
      return store.leftList.map((item, index) => {
        if (item.children?.length) {
          return createVNode("div", {
            "class": "cm-teleport-group-title"
          }, [item.label]);
        }
        return props.renderSourceItem?.(item, checked => {
          onChecked(checked, item);
        }) || createVNode(Checkbox, {
          "key": item.value,
          "disabled": item.disabled,
          "checked": item.checked,
          "onChange": v => onChecked(v, item),
          "label": item.label
        }, null);
      });
    };
    const renderTargetList = () => {
      return value.value.map(val => {
        const item = store.dataMap[val];
        if (!item) return null;
        return props.renderSelectedItem?.(item, () => {
          onRemoveItem(item);
        }) || createVNode("div", {
          "class": "cm-teleport-right-item"
        }, [createVNode(Text, null, {
          default: () => [item.label]
        }), !item.disabled ? createVNode(FeatherX, {
          "class": "cm-teleport-right-item-close",
          "onClick": () => onRemoveItem(item)
        }, null) : null]);
      });
    };
    return () => createVNode("div", {
      "class": classList.value
    }, [createVNode("section", {
      "class": "cm-teleport-left"
    }, [createVNode("div", {
      "class": "cm-teleport-header"
    }, [createVNode("span", {
      "class": "cm-teleport-header-total"
    }, [createTextVNode("\u603B\u4E2A\u6570\uFF1A"), store.originList?.length]), store.checkedAll ? createVNode(Button, {
      "size": "small",
      "theme": "borderless",
      "class": "cm-teleport-select-all",
      "onClick": clearAll
    }, {
      default: () => [createTextVNode("\u53D6\u6D88\u5168\u9009")]
    }) : createVNode(Button, {
      "size": "small",
      "theme": "borderless",
      "class": "cm-teleport-select-all",
      "onClick": selectAll
    }, {
      default: () => [createTextVNode("\u5168\u9009")]
    })]), createVNode("div", {
      "class": "cm-teleport-filter"
    }, [createVNode(Input, {
      "suffix": createVNode(FeatherSearch, null, null),
      "asFormField": false,
      "trigger": "input",
      "onChange": onFilter,
      "placeholder": "\u641C\u7D22",
      "clearable": true
    }, null)]), createVNode("div", {
      "class": "cm-teleport-left-list"
    }, [props.virtual ? createVNode(VirtualList, {
      "items": store.leftList,
      "itemEstimatedSize": 30
    }, {
      default: scope => {
        return createVNode(SourceItem, {
          "item": scope.item,
          "renderSourceItem": props.renderSourceItem,
          "onChecked": onChecked
        }, null);
      }
    }) : renderSourceList()])]), createVNode("section", {
      "class": "cm-teleport-right"
    }, [createVNode("div", {
      "class": "cm-teleport-header cm-teleport-right-header"
    }, [createVNode("span", {
      "class": "cm-teleport-header-total"
    }, [createTextVNode("\u5DF2\u9009\u4E2A\u6570\uFF1A"), value.value.length]), value.value.length ? createVNode(Button, {
      "size": "small",
      "theme": "borderless",
      "class": "cm-teleport-clear",
      "onClick": clearAll
    }, {
      default: () => [createTextVNode("\u6E05\u7A7A")]
    }) : null]), createVNode("div", {
      "class": "cm-teleport-right-list"
    }, [props.virtual ? createVNode(VirtualList, {
      "items": store.rightList,
      "itemEstimatedSize": 30
    }, {
      default: scope => {
        return createVNode(TargetItem, {
          "item": scope.item,
          "renderSelectedItem": props.renderSelectedItem,
          "onRemoveItem": onRemoveItem,
          "store": store
        }, null);
      }
    }) : renderTargetList()])])]);
  }
});
const SourceItem = props => {
  const item = props.item;
  return item.children?.length ? createVNode("div", {
    "class": "cm-teleport-group-title"
  }, [item.label]) : createVNode("div", null, [props.renderSourceItem?.(item, checked => {
    props.onChecked?.(checked, item);
  }) || createVNode(Checkbox, {
    "ref": props.ref,
    "disabled": item.disabled,
    "checked": item.checked,
    "onChange": v => props.onChecked(v, item),
    "label": item.label
  }, null)]);
};
const TargetItem = props => {
  const item = props.item;
  return item ? createVNode("div", null, [props.renderSelectedItem?.(item, () => {
    props.onRemoveItem?.(item);
  }) || createVNode("div", {
    "class": "cm-teleport-right-item"
  }, [createVNode(Text, null, {
    default: () => [item.label]
  }), !item.disabled ? createVNode(FeatherX, {
    "class": "cm-teleport-right-item-close",
    "onClick": () => props.onRemoveItem?.(item)
  }, null) : null])]) : null;
};

export { index as default };
